package com.ag.improvedjava.iterable;

import java.util.Iterator;
import java.util.NoSuchElementException;

final class OfTypeIterable<E, R> implements Iterable<R> {

	private Iterable<E> iterable;
	private Class<R> c;
	
	OfTypeIterable(Iterable<E> iterable, Class<R> c) {
		this.iterable = iterable;
		this.c = c;
	}

	@Override
	public Iterator<R> iterator() {
		return new OfTypeIterator<>(iterable.iterator(), c);
	}
	
}

class OfTypeIterator<E, R> extends UnmodifiableIterator<R> {
	
	private Iterator<E> iterator;
	private boolean iterate;
	private boolean foundNext;
	private R next;
	private Class<R> c;
	
	OfTypeIterator(Iterator<E> iterator, Class<R> c) {
		this.iterator = iterator;
		this.iterate = true;
		this.c = c;
	}

	@Override
	public boolean hasNext() {
		if (iterate) {
			iterate = false;
			foundNext = false;
			while (!foundNext && iterator.hasNext()) {
				try {
					next = c.cast(iterator.next());
					if (next != null) {
						foundNext = true;
					}
				} catch (ClassCastException e) {}
			}
		}
		return foundNext;
	}

	@Override
	public R next() {
		if (!hasNext()) {
			throw new NoSuchElementException();
		}
		iterate = true;
		return next;
	}

}
